package com.real.fact.web.product.application;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.DecimalFormat;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.validation.Errors;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.globant.katari.core.application.ValidatableCommand;
import com.real.fact.web.product.domain.Product;
import com.real.fact.web.product.domain.ProductRepository;

public class UploadProductsCommand implements ValidatableCommand<Void> {

  private CommonsMultipartFile file;

  private ProductRepository productRepository;

  public UploadProductsCommand(ProductRepository productRepository) {
    this.productRepository = productRepository;
  }

  public Void execute() {
    return null;
  }

  public void validate(Errors errors) {
  
    try {
      Workbook wb = WorkbookFactory.create(file.getInputStream());
      Sheet sheet = wb.getSheetAt(0);
      for (int i = 1; i < sheet.getLastRowNum() + 1; i++) {
        Row row = sheet.getRow(i);
  
        String code = String.valueOf(new DecimalFormat("#").format(row.getCell(
            0).getNumericCellValue()));
        String name = row.getCell(1).getStringCellValue();
        String description = row.getCell(2) != null ? row.getCell(2)
            .getStringCellValue() : null;
        String category = row.getCell(3).getStringCellValue();
        String brand = row.getCell(4).getStringCellValue();
        String mesaureType = row.getCell(5) != null ? row.getCell(5)
            .getStringCellValue() : null;
        float rawPrice = (float) (row.getCell(6) != null ? row.getCell(6)
            .getNumericCellValue() : 0);
        float deskPrice = (float) (row.getCell(7) != null ? row.getCell(7)
            .getNumericCellValue() : 0);
        float stock = (float) (row.getCell(8) != null ? row.getCell(8)
            .getNumericCellValue() : 0);
  
        cargarProducto(name, code, description, category, brand, rawPrice,
            deskPrice, stock, mesaureType, null);
      }
    } catch (FileNotFoundException e) {
      errors.rejectValue("file",
          "Archivo no encontrado.");
    } catch (IllegalArgumentException e) {
      errors.rejectValue("file",
          "Formato de archivo invalido.");
    } catch (InvalidFormatException e) {
      errors.rejectValue("file",
          "Error al leer el archivo. Verifique el formato del mismo.");
    } catch (IOException e) {
      errors.rejectValue("file",
          "Error al leer el archivo. Verifique el formato del mismo.");
    } catch (NullPointerException e) {
      errors
          .rejectValue(
              "file",
              "Error al leer el archivo. Alguno de los valores obligatorios no esta completo.");
    }
  }

  private void cargarProducto(String name, String code, String description,
      String category, String brand, float rawPrice, float deskPrice,
      float stock, String mesaureType, String showDescription) {
    Product product = productRepository.findByCode(code);

    // Para los productos que ya estaban cargados:
    // - pisa el precio
    // - suma el stock

    if (product != null) {
      stock += product.getStock();
      product.modify(name, code, description, category, brand, rawPrice,
          deskPrice, stock, mesaureType, showDescription);

    } else {
      product = new Product(name, code, description, category, brand, rawPrice,
          deskPrice, stock, mesaureType, showDescription);
    }
    productRepository.save(product);
  }

  public CommonsMultipartFile getFile() {
    return file;
  }

  public void setFile(CommonsMultipartFile file) {
    this.file = file;
  }

}
